package com.ruoyi.client.service.impl;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.client.domain.entity.BlogUser;
import com.ruoyi.client.service.IBlogUserService;
import com.ruoyi.client.service.LoginService;
import com.ruoyi.common.core.constant.ClientConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.bo.LoginUser;
import com.ruoyi.common.core.enums.LoginType;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.exception.user.UserException;
import com.ruoyi.common.core.utils.MessageUtils;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.satoken.utils.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.function.Supplier;

@Service("password-service")
public class PasswordService implements LoginService {
    @Value("${user.password.maxRetryCount}")
    private Integer maxRetryCount;

    @Value("${user.password.lockTime}")
    private Integer lockTime;
    @Autowired
    IBlogUserService userService;
    @Override
    public String login(String username, String password) {
        BlogUser user = userService.getOne(Wrappers.<BlogUser>lambdaQuery()
            .eq(BlogUser::getStatus,1)
            .eq(BlogUser::getUsername, username));
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        checkLogin(username, () ->!BCrypt.checkpw(password,user.getPassword()));
        StpUtil.login(user.getId(),SaLoginModel.create().setExtraData(Map.of("client:user",user)).setIsLastingCookie(false));
//        StpUtil.login(user.getId(),false);
        return StpUtil.getTokenValue();
    }

    private void checkLogin(String username, Supplier<Boolean> supplier) {
        String err_key = "client:" + username + ClientConstants.PWD_ERR_CNT_KEY;
        int err_count = ObjectUtil.defaultIfNull(RedisUtils.getCacheObject(err_key),0);
        if (err_count >= maxRetryCount) {
            throw new UserException("错误次数达到" + maxRetryCount + "次，请" + lockTime + "后重试");
        }
        if (supplier.get()) {
            err_count++;
            RedisUtils.setCacheObject(err_key,err_count);
            if (err_count >= maxRetryCount) {
                throw new UserException("错误次数达到" + maxRetryCount + "次，请" + lockTime + "后重试");
            }
            else {
                throw new UserException("错误" + maxRetryCount + "次");
            }
        }
        RedisUtils.deleteObject(err_key);
    }
    @Override
    public void logout() {
        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
        } catch (NotLoginException ignored) {
        } finally {
            try {
                StpUtil.logout();
            } catch (NotLoginException ignored) {
            }
        }
    }
}
